/*
	NounStructure.h

	This is the base class for objects that can be built on planets
	(c)2000 Palestar Inc, Richard Lyle
*/

#ifndef NOUNSTRUCTURE_H
#define NOUNSTRUCTURE_H

#include "NounGame.h"
#include "Constants.h"
#include "GameDll.h"

//----------------------------------------------------------------------------

class NounPlanet;		// forward declare
class NounShip;

class DLL NounStructure : public NounGame
{
public:
	DECLARE_WIDGET_CLASS();
	DECLARE_PROPERTY_LIST();

	// Types
	typedef Reference< NounStructure >				Ref;
	typedef WidgetReference< NounStructure >		wRef;
	typedef ResourceType							Resource;
	
	enum Flags {
		FLAG_ACTIVE			= 0x00000001,
		FLAG_WORKER_SHORT	= 0x00000002,
		FLAG_POWER_SHORT	= 0x00000004,
		FLAG_TECH_SHORT		= 0x00000008,
	};

	// Construction
	NounStructure();

	// Widget interface
	bool			read( InStream & input );
	// Node interface
	virtual void	onAttached();
	void			render( RenderContext &context, 
						const Matrix33 & frame, 
						const Vector3 & position );

	// Noun interface
	NounType		nounType() const;
	bool			canBeDetected() const;
	float			baseSignature() const;
	bool			canDamage( dword type ) const;
	CharString		status() const;					// status string
	bool			canInteract( NounInteraction nInteraction, Noun * pWith );

	void			initialize();
	void			interact( NounInteraction nInterfaction, Noun * pWidth, int nTicks );
	void			inflictDamage( dword nWhen, Noun * pFrom, int damage, dword type, 
						const Vector3 & direction );

	// Accessors
	virtual int		maxDamage() const;				// how much damage can this structure take
	virtual int		repairRate() const;				// damaged repaired per second
	virtual int		buildTechnology() const;		// technology on the planet required to build this structure
	virtual int		buildTime() const;				// time to build this structure in seconds
	virtual int		buildCost() const;				// cost to build this structure in resources
	virtual dword	buildFlags() const;				// planetary flags required to build this structure

	virtual Color	color() const;					// HUD color 

	virtual bool	canBuild( NounPlanet * pPlanet ) const;	

	virtual dword	planetFlags() const;			// flags assigned to the planet
	virtual int		workers() const;				// workers needed
	virtual int		power() const;					// power required/generated
	virtual int		food() const;					// food generated by this structure
	virtual int		habitat() const;				// habitat provided by this structure
	virtual int		mining() const;					// mining from this structure
	virtual int		research() const;				// research generated by this structure
	virtual int		production() const;				// production added by this structure
	virtual int		technology() const;				// technology level needed for this structure to operate

	virtual bool	usable( NounShip * pShip ) const;			// can this structure be used by the specified ship
	virtual CharString	
					useTip( NounShip * pShip ) const;			// tool tip for using this structure
	virtual bool	useConfirm( NounShip * pShip ) const;		// should the use of this structure be confirmed?
	virtual CharString	
					useConfirmMessage( NounShip * pShip ) const;	// use confirmation message
	virtual void	use( dword nWhen, NounShip * pShip );		// use this structure

	u16				hex() const;					// current structure hex on the planet
	int				damage() const;					// amount of damage sustained
	Material *		icon() const;					// icon for the structure

	bool			active() const;					// is structur active
	bool			isPaused() const;				// is this structure currently paused
	int				buildCompleted() const;			// how much has been built

	// Mutators
	void			setHex( u16 nHex );
	bool			updatePosition();				// update position based on current hex
	void			setActive( bool active );		// set building active
	void			setDamage( int damage );

	void			scrap();						// called by VerbScrap()
	bool			build();						// build on structure
	void			repair();						// repair the structure

	virtual void	destroy( Noun * pKiller );		// call by VerbDestroyStructure()

	// helpers
	bool			isBuilding() const;				// is this structure still being built
	int				buildComplete() const;			// percentage complete
	NounPlanet *	planet() const;					// planet this structure is on

	// static
	static bool		s_Render;						// render the structures

protected:
	// Data
	u16				m_nHex;							// hex for this structure
	u16				m_nBuildTime;				// how long to build this object
	u16				m_Damage;						// damage to this object
};

//----------------------------------------------------------------------------

inline u16 NounStructure::hex() const
{
	return m_nHex;
}

inline int NounStructure::damage() const
{
	return m_Damage;
}

inline Material * NounStructure::icon() const
{
	return WidgetCast<Material>( nounContext()->resource( "ICON" ) );
}

inline bool NounStructure::active() const
{
	return (flags() & FLAG_ACTIVE) != 0 
		&& (flags() & (FLAG_WORKER_SHORT|FLAG_POWER_SHORT|FLAG_TECH_SHORT)) == 0 
		&& m_nBuildTime >= buildTime();
}

inline bool NounStructure::isPaused() const
{
	return (m_Flags & FLAG_ACTIVE) == 0;
}

inline int NounStructure::buildCompleted() const
{
	return m_nBuildTime;
}

inline bool NounStructure::isBuilding() const
{
	return m_nBuildTime < buildTime();
}

inline int NounStructure::buildComplete() const
{
	return (m_nBuildTime * 100) / buildTime();
}

//----------------------------------------------------------------------------



#endif

//----------------------------------------------------------------------------
//EOF
